#ifndef _VEC3_H_
#define _VEC3_H_

#include <math.h>

namespace math
{

///////////////////////////////////////////////////////
///	\brief	Vector class that provides basic vector functionality
/// flexibility is preferred over speed.
///////////////////////////////////////////////////////
class Vec3 
{
  public:
	Vec3(float* _Vec);
	Vec3(float _x,float _y,float _z);
	Vec3();
	
	inline float	Magnitude() const	{		return (float)sqrt(	MagSqr());					};
	inline float	MagSqr() const      {		return (x*x)  +	(y*y) + 	(z*z);				};	
	inline	float	Manhatten() const 	{		return (float)(fabs(x) + fabs(y) + fabs(z));	};
	
	Vec3&			Normalize();
	int				Concurrent(const Vec3&) const;
	Vec3&			Modulate(const Vec3& _Val);	// (This.x*_Val.x, This.y*_Val.y, This.z*_Val.z);

	Vec3			LowVec(const Vec3& _A) const;
	Vec3			HighVec(const Vec3& _A) const;

	void			Reset();

	// access points for LUA Bind
	float			GetX() const { return x; };
	void			SetX(float f) { x = f; };
	float			GetY() const { return y; };
	void			SetY(float f) { y = f; };
	float			GetZ() const { return z; };
	void			SetZ(float f) { z = f; };


	float*			Get() { return &x; };
	// Get adress
	operator float *() { return &x;};
	Vec3& operator = ( const Vec3& _Vec) ;
	Vec3& operator+= ( const Vec3& _Vec) ;
	Vec3& operator-= ( const Vec3& _Vec) ;
	Vec3& operator*= ( const float& _f) ;
	Vec3& operator/= ( const float& _f) ;

    Vec3 operator + () const;
    Vec3 operator - () const
	{
		return Vec3(-x, -y, -z);
	}

    Vec3 operator + ( const Vec3& v) const
	{
		return Vec3(x+v.x, y+v.y, z+v.z);
	}
    Vec3 operator - ( const Vec3& v) const
	{
		return Vec3(x-v.x, y-v.y, z-v.z);
	}

    Vec3 operator * ( float c) const
	{
		return Vec3(x*c, y*c, z*c);
	}
    Vec3 operator * ( const Vec3& ) const;
    Vec3 operator / ( float ) const;

	friend Vec3 operator * ( float f , const Vec3& v)
	{
		return Vec3(v.x*f, v.y*f, v.z*f);
	}

	float operator == ( const Vec3& ) const;
    float operator != ( const Vec3& ) const;

	float			x, y, z;
};
} // end namespace math

math::Vec3 IntersectPlane(const math::Vec3& vNorm,float d, const math::Vec3& p1, const math::Vec3& p2);
math::Vec3 LerpVec3(const math::Vec3& From, const math::Vec3& To, float t);

// Operator overloads for vectors
/*math::Vec3 operator+(const math::Vec3&  vVec1, const math::Vec3&  vVec2);
math::Vec3 operator-(const math::Vec3&  vVec) ;
math::Vec3 operator-(const math::Vec3&  vVec1, const math::Vec3&  vVec2) ;
math::Vec3 operator*(const math::Vec3&  vVec1, float fScalar) ;
math::Vec3 operator*(float fScalar, const math::Vec3&  vVec1) ;
math::Vec3 operator/(const math::Vec3&  vVec1,float fScalar) ;**/
float   operator^(const math::Vec3&  vVec1, const math::Vec3&  vVec2) ;   // DOT product
//math::Vec3 operator*(const math::Vec3&  vVec1, const math::Vec3&  vVec2) ;   // CROSS product



#endif // _VEC3_H_